package org.example.business.endpoint.http;

import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.example.objevent.event.Event;
import org.example.objevent.event.EventBus;
import org.example.objevent.executor.EventExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.net.InetSocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class HttpSocketManager {

    @Autowired
    private EventBus bus;

    @Autowired
    private EventExecutor executor;

    private Map<String, HttpSocket> httpSocketMap = new ConcurrentHashMap<>();

    public HttpSocket getSocket(ChannelHandlerContext ctx){
        return getSocket(contractSocketKey(ctx));

    }

    public HttpSocket getSocket(String socketKey){
        return httpSocketMap.get(socketKey);

    }

    public HttpSocket delSocket(HttpSocket httpSocket){
        return httpSocketMap.remove(httpSocket.getSocketKey());

    }

    public HttpSocket addSocket(HttpSocket httpSocket){
        return httpSocketMap.put(httpSocket.getSocketKey(), httpSocket);

    }

    @PostConstruct
    private void setup(){
        executor.getScheduler().scheduleAtFixedRate(new SocketCleaner(), 1000, 100, TimeUnit.MILLISECONDS);

    }

    private String contractSocketKey(ChannelHandlerContext ctx){
        InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
        return HttpSocket.buildKey(remoteAddress.getAddress().getHostAddress(), "" + remoteAddress.getPort());

    }

    private class SocketCleaner implements Runnable{

        @Override
        public void run() {

            httpSocketMap.forEach((key, value)->{

                if(value.getState().equals(HttpSocket.State.Closed)){

                    bus.publish(new Event("CLEAN_CONNECTION", value));

                }

            });

        }

    }
}
